Appearance
2690. 无穷方法对象
ts
function createInfiniteObject(): Record<string, () => string> {
return new Proxy({},{
get:(target,props)=>{
return ()=>props;
}
})
};Proxy 的 get 陷阱
这里直接用到 Proxy 的一个核心能力:拦截属性访问。
正常情况下,访问对象不存在的属性会得到 undefined。但有了 get 陷阱,任何属性访问都会被拦截。这里无论访问什么属性名,都返回一个函数,函数被调用时再返回属性名本身。
js
const obj = createInfiniteObject();
obj.hello(); // → "hello"
obj.world(); // → "world"
obj.any.thing.you.want(); // → "want"(最后一次属性访问)最后一行的行为容易误解。obj.any.thing.you.want() 实际上是:
obj.any→ 返回一个函数(但没调用).thing→ 访问函数的 thing 属性,但函数不是 Proxy,所以undefined.you→ 同上.want()→ 报错,因为undefined不可调用
要让链式调用生效,需要每个属性访问都返回 Proxy:
ts
function createInfiniteObject(): any {
return new Proxy({}, {
get: (target, props) => {
return createInfiniteObject(); // 链式调用的关键
}
});
};这样 obj.a.b.c() 就能递归生成新 Proxy。
为什么这里返回函数而不是递归代理
题目要求 obj.anything() 返回 "anything",也就是把属性名作为字符串返回。递归 Proxy 方案里,obj.a.b.c() 最后只能落到 "c",但 Proxy 本身并不能区分「最后一次属性访问」和「链式调用中间步」。这里用 () 作为终点标记,因此解法选择返回函数。
实际应用
Proxy 的动态属性拦截在前端框架的响应式系统里非常常见(例如 Vue 3 的 track/trigger 依赖追踪),但“无限方法对象”这个具体模式在业务代码里并不常见,更多是一个 Proxy 能力演示。
